/* 
 * Cashbox is the legal property of its developers, whose names are listed in the copyright file included
 * with this source distribution.
 * 
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
 * General Public License as published by the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 * Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this program; if not,
 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#import <Cashbox/CBObject.h>

enum {
	CBCriticalImporterError = 1,
	CBCautionaryImporterError = 2
};
typedef NSUInteger CBImporterErrorCode;

@interface CBImporter : CBObject {
	NSMutableArray *accounts;
	NSMutableArray *orphanTransactions;
	NSMutableArray *allTransactions;
	NSMutableArray *transfers;
	NSMutableArray *labels;
	NSMutableArray *errors;
	BOOL importComplete, readComplete;
}

// an array of all registered importer classes
+ (NSArray *)registeredImporters;
// an array of strings containing all handled extensions
+ (NSArray *)handledExtensions;
// returns the first importer that can handle a specific extension
// (leave off the dot) or nil if no importer exists
+ (CBImporter *)importerForExtension:(NSString *)extension;

// begin an import by reading the file
// after that, call importData
- (void)readFile:(NSString *)path;

// returns whether or not importing has actually occurred
- (BOOL)readComplete;

// importing data will not occur if there are any errors
// prior to attempting to import.  if you have presented
// the errors to the user, and the user has accepted the
// import anyway, you can use the - [clearError] function
// to clear any errors and then the import will go through
- (void)importData;

// returns whether or not importing has actually occurred
- (BOOL)importComplete;

- (NSArray *)accounts; // an array of CBImportAccounts, KVO
- (NSArray *)labels; // an array of CBImportLabels, KVO

// returns any errors (NSError objects) that might have
// occurred after reading or importing the data
- (NSArray *)errors;
// clears the errors (use after presenting errors)
- (void)clearErrors;

@end

// none of these notifications have userInfo and all of them
// are self explanitory
extern NSString *CBImporterWillBeginReadingNotification;
extern NSString *CBImporterDidFinishReadingNotification;
extern NSString *CBImporterWillBeginImportingNotification;
extern NSString *CBImporterDidFinishImportingNotification;
// the userInfo dict contans a string with the description of the progress
// and a number with the percent (0-1) that it's finished
extern NSString *CBImporterDidProgressImportingNotification; // keys: @"CBDescription" @"CBPercent"

@interface CBImporter (CBSubclassingInterface)

// for subclassers
// ------------------------

// this method must be called in the + load method
// to register the importer
+ (void)registerImporter:(Class)importer;
// returns an array of extensions that the importers
// of the class can handle
+ (NSArray *)canHandleExtensions;

// note: subclassers should not override any of the above
// methods.  it should not be needed and could interfere
// with the import process.

// override this method to add information from the given file.
// call methods such as addAccount..., addTransaction..., etc.
- (void)addDataFromFile:(NSString *)file;

// adds an account that will later be imported with importData
// returns a reference to some sort of NSObject (what it is could
// change in the future, so only count on NSObject protocol methods
// being available) in ref (pass NULL if you don't want the
// reference that is used when adding transactions or updating
// the keys for the account.  the reference object must be
// the exact same object, not a copy
- (void)addAccountWithName:(NSString *)name
			additionalInfo:(NSString *)additionalInfo
					  keys:(NSArray *)keys
				 reference:(id <NSObject> *)ref;

// updates the account keys of the account.  the reference must be
// the exact same object that was returned when adding the account
- (void)updateAccountKeys:(NSArray *)keys
				reference:(id <NSObject>)ref;

// adds a transaction to the account with an attributes dictionary
// that should have the same keys as the account.  the reference must
// be the exact same object that was returned when adding the account.
// if not, it will be added to an untitled account.
// the date paramater is date is either an NSDate or an NSDictionary
// that has NSNumbers for DATE_MONTH, DATE_DAY, and DATE_YEAR keys
// (NSDate is faster, but the dictionary allows for dayMonthSwitch
// checking)
- (void)addTransactionToAccount:(id <NSObject>)accountReference
				 withAttributes:(NSDictionary *)attributes
						   date:(NSDate *)date
					 reconciled:(BOOL)reconciled
						cleared:(BOOL)cleared
					  labelName:(NSString *)label
					  reference:(id <NSObject> *)ref;

// updates the date of the transaction.  the reference must be the
// exact same object that was returned when adding the transaction
- (void)updateTransactionDate:(NSDate *)date
					reference:(id <NSObject>)ref;

// links two transactions together and makes them a transfer transaction
// values in the attributes dictionary should be set in both of them
// the references must be the exact same objects returned when creating
// the transactions
- (void)createTransfersFor:(id <NSObject>)firstReference
					andFor:(id <NSObject>)secondReference;

// notes that a label is being used when importing the account.  the label
// is added only if it doesn't already exist.  if color is nil, a color
// from the ColorListColors.h is used
- (void)noteLabel:(NSString *)label
		withColor:(NSColor *)color;

// called before importing any data.  any last minute adjustments of data
// can be done here.  the integrity of the data will not be checked (no errors
// will be added), so be careful making changes.  default implementation
// does nothing, so no need to call super.
- (void)importDataWillBegin;
// called after the data is imported.  cleanup can be done here if needed.
// the default implemenation does nothing, so no need to call super.
- (void)importDataDidFinish;

// can be used by subclasses to add any errors that occur
// while reading the file
- (void)addError:(NSError *)error;

// returns an array of all the keys that the importer can handle.  subclasses
// can override to filter out keys that it can't/doesn't handle
+ (NSArray *)defaultKeys;

@end
